/*******************************************************************************
 * Copyright (c) 2005, 2014 springside.github.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.modules.persistence;


import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;

public class DynamicSpecifications {

	
	public static <T> Specification<T> bySearchFilter(ServletRequest request) {
		Map<String, Object> searchParams = new HashMap<String, Object>();
		return bySearchFilter(request,searchParams);
	}
	public static <T> Specification<T> bySearchFilter(ServletRequest request,Map<String, Object> searchParams) {
		return bySearchFilter(request,searchParams,new SearchSpecFilter[]{});
	}
	public static <T> Specification<T> bySearchFilter(ServletRequest request,SearchSpecFilter...searchSpecFilter) {
		return bySearchFilter(request,new HashMap<String, Object>(),searchSpecFilter);
	}
	
	public static <T> Specification<T> bySearchFilter(ServletRequest request,Map<String, Object> searchParams,SearchSpecFilter...searchSpecFilter) {
		Map<String, SearchFilter> filters = SearchFilter.parse(request);
		filters.putAll(SearchFilter.parse(searchParams));
		if(filters.values().size()>0) {
			Collection<SearchFilter> valueCollection = filters.values();
			SearchFilter[] valueArray = new SearchFilter[valueCollection.size()];
			filters.values().toArray(valueArray);
			SearchSpecFilter searchSpec = bulidSearchSpecFilter(valueArray);//SearchSpecFilter 之间的关联只能是同时是and 或者同时是or
			if(searchSpecFilter != null) {
				SearchSpecFilter[] searchSpecArray = new SearchSpecFilter[searchSpecFilter.length+1];
				int i= 0;
				for(SearchSpecFilter fil :searchSpecFilter) {
					searchSpecArray[i] = fil;
					i++;
				}
				searchSpecArray[searchSpecFilter.length] = searchSpec;
				Specification<T> spec = buildSpecification(searchSpecArray);
				return spec;
			}else {
				Specification<T> spec = buildSpecification(searchSpec);
				return spec;
			}
		}else {
			Specification<T> spec = buildSpecification(searchSpecFilter);
			return spec;
		}
		
		
	}
	
	
	
	public static Specification buildSpecification(SearchSpecFilter...filters ){
		Specifications result = null;
			for(SearchSpecFilter searchSpecFilter:filters){
				if(result==null) {
	                result = Specifications.where(searchSpecFilter.getSpes());
	            } else {
	                if("or".equalsIgnoreCase(searchSpecFilter.getType())) {
	                    result = result.or(searchSpecFilter.getSpes());
	                } else {
	                    result = result.and(searchSpecFilter.getSpes());
	                }
	            }
		   }
		
        return result;
	}
	/***
	 * 装换过程
	 * 1、将request中参数转换为SearchFilter类型 
	 * 2、将SearchFilter类型转为SearchSpecFilter类型  
	 * 3、将SearchSpecFilter类型转为Specification类型
	 * 说明  首先要确认SearchFilter之间是什么关系  or 还是  and
	 * 再次确认各个SearchSpecFilter之间的关系
	 * **/
	
	
	public static SearchSpecFilter bulidSearchSpecFilter(String type, SearchFilter... searchFilter){
		
		Specifications result = null;
		SearchSpecFilter searchSpecFilter = null;
		result= bulidSearchSpec(searchFilter);
        searchSpecFilter = new SearchSpecFilter(type, result);//多个条件之间使用type类型进行关联
        return searchSpecFilter;
	}
	/*
	 * 默认为and
	 * 
	 * **/
	public static SearchSpecFilter bulidSearchSpecFilter(SearchFilter... searchFilter){
		@SuppressWarnings("rawtypes")
		Specifications result = null;
		SearchSpecFilter searchSpecFilter = null;
		result = bulidSearchSpec(searchFilter);
        searchSpecFilter = new SearchSpecFilter(result);
        return searchSpecFilter;
	}
	
	
	/**
	 * 公用方法创建Specifications
	 * 
	 * */
	
	
	private static Specifications<?> bulidSearchSpec(SearchFilter... searchFilter){
		Specifications<?> result = null;
		for(SearchFilter filter : searchFilter) {
            if(result==null) {
                result = Specifications.where(new BaseSpecification(filter));
            } else {//默认为and 如果设置了  or  进行or查询
                if("or".equalsIgnoreCase(filter.getType())) {
                    result = result.or(new BaseSpecification(filter));
                } else {
                    result = result.and(new BaseSpecification(filter));
                }
            }
        }
		return result;
	}
	
	
	
	
	
	

	/**
	 * 创建分页请求.
	 */
	public static PageRequest buildPageRequest(ServletRequest request, Sort sort) {
		Integer pageInt = 0;//初始页
		Integer pageSizeInt = 10;//默认条数
		String page = request.getParameter("pageNumber");
		String pageSize = request.getParameter("pageSize");
		if(StringUtils.isNotEmpty(page)){//当前页
			pageInt = Integer.parseInt(page)-1;
		}
		if(StringUtils.isNotEmpty(pageSize)){//每页条数
			pageSizeInt = Integer.parseInt(pageSize);
		}
		return new PageRequest(pageInt, pageSizeInt, sort);
	}
}
